import { useEffect, useState } from 'react';
import { createRoot, Root } from 'react-dom/client';

interface ModalContentProps {
  title?: string;
  closable?: boolean;
  children?: React.ReactNode;
  onClose?: () => void;
}

interface ModalProps extends ModalContentProps {
  visible?: boolean;
}

export default function Modal(props: ModalProps) {
  const [visible, setVisible] = useState(props.visible);
  const withCmd = isOpenWithCmd();

  const close = () => {
    if (withCmd) Modal.cancel();
    else setVisible(false);
    props.onClose?.();
  };

  const onMaskClick = (e: React.MouseEvent) => {
    if (props.closable !== false) {
      const target = e.target as HTMLElement;
      if (target.getAttribute('data-type')?.includes('modal-wrapper')) close();
    }
  };

  useEffect(() => {
    if (!withCmd) {
      if (visible && !props.visible) setVisible(false);
      else if (!visible && props.visible) setVisible(true);
    }
  }, [props.visible]);

  return (
    <div
      className={`fixed left-0 top-0 z-10 flex h-screen w-screen items-center justify-center bg-black bg-opacity-60 ${!visible && !withCmd ? 'hidden' : ''}`}
      data-type='modal-wrapper'
      onClick={onMaskClick}
    >
      <div className='min-w-80 rounded-md bg-white'>
        {props.title ? <div className='border-b p-4 text-xl font-bold'>{props.title}</div> : null}
        {props.children ? <div className='p-2 text-lg'>{props.children}</div> : null}
      </div>
    </div>
  );
}

let container: HTMLDivElement | null = null;
let root: Root | null = null;

Modal.open = (props: ModalContentProps) => {
  container = document.createElement('div');
  container.setAttribute('data-type', 'modal-root');
  root = createRoot(container);
  root.render(<Modal {...props} />);
  document.body.appendChild(container);
};

Modal.cancel = () => {
  if (container && root) {
    root.unmount();
    document.body.removeChild(container);
    container = root = null;
  }
};

/**
 * 通过 command 打开，会比通过 state 多一层容器，可以借此判断打开方式
 */
const isOpenWithCmd = () => !!document.body.querySelector('[data-type="modal-root"]');
